package org.alis.rpc.common.serializer.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoPool;
import org.alis.rpc.common.exception.SerializerException;
import org.alis.rpc.common.serializer.Serializer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @author lc
 * @version v1.0.0
 * @date 2020/8/20 16:51
 * @className KryoP.class
 */
public class KryoSerializer implements Serializer {
    private KryoPool pool = KryoPoolFactory.getKryoPoolInstance();

    @Override
    public <T> byte[] serializer(T obj) {
        Kryo kryo = pool.borrow();
        try(ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Output out = new Output(byteArrayOutputStream)){
            kryo.writeObject(out, obj);
            return byteArrayOutputStream.toByteArray();
        }catch (Exception e){
            throw new SerializerException(e);
        }finally {
            pool.release(kryo);
        }
    }

    @Override
    public <T> T deserializer(byte[] bytes, Class<T> clazz) {
        Kryo kryo = pool.borrow();
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
             Input in = new Input(byteArrayInputStream)) {
            return kryo.readObject(in, clazz);
        } catch (Exception e) {
            throw new SerializerException(e);
        } finally {
            pool.release(kryo);
        }
    }

}